package com.example.service;

import com.example.common.enums.ResultCodeEnum;
import com.example.common.enums.RoleEnum;
import com.example.common.enums.SegmentEnum;
import com.example.common.enums.WeekEnum;
import com.example.entity.Account;
import com.example.entity.Choice;
import com.example.entity.Course;
import com.example.entity.Curriculum;
import com.example.exception.CustomException;
import com.example.mapper.ChoiceMapper;
import com.example.mapper.CourseMapper;
import com.example.utils.TokenUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 选课信息表业务处理
 **/
@Service
public class ChoiceService {

    @Resource
    private ChoiceMapper choiceMapper;

    @Resource
    private CourseMapper courseMapper;

    /**
     * 新增
     */
    public void add(Choice choice) {
        //当前选的课
        Course course = courseMapper.selectById(choice.getCourseId());

        //1.查看这门课选满了没有
        //两个方式：
        //1).在选课信息表里面查询该课被选的次数
        //2).在课程信息表中加1个字段——已选人数
        List<Choice> list = choiceMapper.selectByCourseId(choice.getCourseId());
        if (course.getNum().equals(list.size())) {
            throw new CustomException(ResultCodeEnum.COURSE_NUM_ERROR);
        }


        //2.查看有没有选课的时间冲突
        List<Choice> slist = choiceMapper.selectByStudentId(choice.getStudentId());
        for (Choice dbChoice : slist) {
            Course tmpCourse = courseMapper.selectById(dbChoice.getCourseId());
            if (course.getWeek().equals(tmpCourse.getWeek()) && course.getSegment().equals(tmpCourse.getSegment())) {
                throw new CustomException("-1", "您之前已经选过" + tmpCourse.getName() + ",与该门课的上课时间冲突，请重新选择");
            }
        }


        choiceMapper.insert(choice);
    }

    /**
     * 删除
     */
    public void deleteById(Integer id) {
        choiceMapper.deleteById(id);
    }

    /**
     * 批量删除
     */
    public void deleteBatch(List<Integer> ids) {
        for (Integer id : ids) {
            choiceMapper.deleteById(id);
        }
    }

    /**
     * 修改
     */
    public void updateById(Choice choice) {
        choiceMapper.updateById(choice);
    }

    /**
     * 根据ID查询
     */
    public Choice selectById(Integer id) {
        return choiceMapper.selectById(id);
    }

    /**
     * 查询所有
     */
    public List<Choice> selectAll(Choice choice) {
        return choiceMapper.selectAll(choice);
    }

    /**
     * 分页查询
     */
    public PageInfo<Choice> selectPage(Choice choice, Integer pageNum, Integer pageSize) {
        Account currentUser = TokenUtils.getCurrentUser();
        //设置权限，教师和学生只能看到自己的信息
        if (RoleEnum.TEACHER.name().equals(currentUser.getRole())) {
            choice.setTeacherId(currentUser.getId());
        }
        if (RoleEnum.STUDENT.name().equals(currentUser.getRole())) {
            choice.setStudentId(currentUser.getId());
        }
        PageHelper.startPage(pageNum, pageSize);
        List<Choice> list = choiceMapper.selectAll(choice);
        return PageInfo.of(list);
    }

    /**
     * @Description: 生成对应学生的选课课表
     * @Param:
     * @return: java.util.List<com.example.entity.Curriculum>
     * @Author: 周名浩
     * @Date: 2024/2/18
     */
    public List<Curriculum> getCurriculum() {
        Account user = TokenUtils.getCurrentUser();

        //查询所有该学生的选课信息
        Choice choice = new Choice();
        choice.setStudentId(user.getId());
        List<Choice> choiceList = choiceMapper.selectAll(choice);

        List<Curriculum> list = new ArrayList<>();
        //按照第几大节与周几处理数据（共有7大节，8列数据）

        //处理第1大节：第一大节（09:00 ~ 10:20）
        Curriculum first = new Curriculum();
        first.setSegment(SegmentEnum.FIRST.segment);
        processWeek(first, getWeekChoiceList(choiceList, SegmentEnum.FIRST.segment));
        list.add(first);

        //处理第2大节：第二大节（10:40 ~ 12:00）
        Curriculum second = new Curriculum();
        second.setSegment(SegmentEnum.SECOND.segment);
        processWeek(second, getWeekChoiceList(choiceList, SegmentEnum.SECOND.segment));
        list.add(second);

        //处理第3大节：第三大节（14:00 ~ 15:20）
        Curriculum third = new Curriculum();
        third.setSegment(SegmentEnum.THIRD.segment);
        processWeek(third, getWeekChoiceList(choiceList, SegmentEnum.THIRD.segment));
        list.add(third);

        //处理第4大节：第四大节（15:30 ~ 16:50）
        Curriculum fourth = new Curriculum();
        fourth.setSegment(SegmentEnum.FOURTH.segment);
        processWeek(fourth, getWeekChoiceList(choiceList, SegmentEnum.FOURTH.segment));
        list.add(fourth);

        //处理第5大节：第五大节（17:00 ~ 18:20）
        Curriculum fifth = new Curriculum();
        fifth.setSegment(SegmentEnum.FIFTH.segment);
        processWeek(fifth, getWeekChoiceList(choiceList, SegmentEnum.FIFTH.segment));
        list.add(fifth);

        //处理第6节：第六大节（19:00 ~ 20:20）
        Curriculum sixth = new Curriculum();
        sixth.setSegment(SegmentEnum.SIXTH.segment);
        processWeek(sixth, getWeekChoiceList(choiceList, SegmentEnum.SIXTH.segment));
        list.add(sixth);

        //处理第7大节：第七大节（20:30 ~ 21:50）
        Curriculum seventh = new Curriculum();
        seventh.setSegment(SegmentEnum.SEVENTH.segment);
        processWeek(seventh, getWeekChoiceList(choiceList, SegmentEnum.SEVENTH.segment));
        list.add(seventh);


        return list;

    }

    /**
     * @Description: 处理当前第几大节的所有选课信息（周一到周日）
     * @Param: choiceList
     * @return: java.util.List<com.example.entity.Choice>
     * @Author: 周名浩
     * @Date: 2024/2/18
     */
    private static List<Choice> getWeekChoiceList(List<Choice> choiceList, String segement) {
        return choiceList.stream().filter(x -> x.getSegment().equals(segement)).collect(Collectors.toList());
    }


    /**
     * @Description: 处理周一到周日的数据
     * @Param: curriculum 当前大节
     * @Param list 当前大节的所有课程
     * @return: void
     * @Author: 周名浩
     * @Date: 2024/2/18
     */
    private void processWeek(Curriculum curriculum, List<Choice> list) {
        //根据当前大节对每个星期进行比较，如果当前大节与当前星期有数据则表示（该星期的该大节有课）
        //直接将curriculum中set进去，因为又是同一个类，不需要跨类所以不用特意封装返回出去

        //星期一
        Optional<Choice> first = list.stream().filter(x -> x.getWeek().equals(WeekEnum.MONDAY.week)).findFirst();
        first.ifPresent(choice -> curriculum.setMonday(choice.getName()+"("+choice.getTeacherName()+")"));
        //星期二
        Optional<Choice> second = list.stream().filter(x -> x.getWeek().equals(WeekEnum.TUESDAY.week)).findFirst();
        second.ifPresent(choice -> curriculum.setTuesday(choice.getName()+"("+choice.getTeacherName()+")"));
        //星期三
        Optional<Choice> wednesday = list.stream().filter(x -> x.getWeek().equals(WeekEnum.WEDNESDAY.week)).findFirst();
        wednesday.ifPresent(choice -> curriculum.setWednesday(choice.getName()+"("+choice.getTeacherName()+")"));
        //星期四
        Optional<Choice> thursday = list.stream().filter(x -> x.getWeek().equals(WeekEnum.THURSDAY.week)).findFirst();
        thursday.ifPresent(choice -> curriculum.setThursday(choice.getName()+"("+choice.getTeacherName()+")"));
        //星期五
        Optional<Choice> friday = list.stream().filter(x -> x.getWeek().equals(WeekEnum.FRIDAY.week)).findFirst();
        friday.ifPresent(choice -> curriculum.setFriday(choice.getName()+"("+choice.getTeacherName()+")"));
        //星期六
        Optional<Choice> saturday = list.stream().filter(x -> x.getWeek().equals(WeekEnum.SATURDAY.week)).findFirst();
        saturday.ifPresent(choice -> curriculum.setSaturday(choice.getName()+"("+choice.getTeacherName()+")"));
        //星期日
        Optional<Choice> sunday = list.stream().filter(x -> x.getWeek().equals(WeekEnum.SUNDAY.week)).findFirst();
        sunday.ifPresent(choice -> curriculum.setSunday(choice.getName()+"("+choice.getTeacherName()+")"));

    }
}
